home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
Other Langs
/
MacPerl ƒ
/
Perl Source ƒ
/
MacPerl
/
MPPreferences.c
< prev
next >
Wrap
Text File
|
1993-12-11
|
17KB
|
794 lines
/*********************************************************************
Project : MacPerl - Real Perl Application
File : MPPreferences.c - Handle Preference Settings
Author : Matthias Neeracher
A lot of this code is borrowed from 7Edit written by
Apple Developer Support UK
Started : 08Dec93 Language : MPW C
Modified : 08Dec93 MN Separated from MPUtils
Last : 08Dec93
*********************************************************************/
#include <PLStringFuncs.h>
#include <Events.h>
#include <Traps.h>
#include <Dialogs.h>
#include <Fonts.h>
#include <Packages.h>
#include <ToolUtils.h>
#include <AppleEvents.h>
#include <TFileSpec.h>
#include <Folders.h>
#include <Resources.h>
#include <OSUtils.h>
#include <Files.h>
#include <Lists.h>
#include <Icons.h>
#include <string.h>
#include <GUSI.h>
#include <Desk.h>
#include <ctype.h>
#include <stdio.h>
#include "MPPreferences.h"
#include "MPUtils.h"
#include "MPWindow.h"
#include <patchlevel.h>
pascal void OpenPreferenceFile(FSSpec * spec)
{
Str255 name;
short oldResFile;
short res;
short ** defaultfont;
PerlPrefs **prefs;
oldResFile = CurResFile();
gPrefsFile = HOpenResFile(spec->vRefNum, spec->parID, spec->name, fsRdWrPerm);
if (gPrefsFile == -1) {
gPrefsFile = 0;
return;
}
if (!Get1Resource('STR#', LibraryPaths)) {
Handle lib;
short count = 1;
char len;
char * libpath;
FSSpec libspec;
libspec.vRefNum = gAppVol;
libspec.parID = gAppDir;
PLstrcpy(libspec.name, "\plib");
libpath = FSp2FullPath(&libspec);
len = strlen(libpath);
PtrToHand((Ptr) &count, &lib, sizeof(short));
PtrAndHand((Ptr) &len, lib, 1);
PtrAndHand(libpath, lib, len);
AddResource(lib, 'STR#', LibraryPaths, "\p");
}
if (!(defaultfont = (short **) Get1Resource('PFNT', 128))) {
Handle font;
PtrToHand((Ptr) &gFormat.size, &font, sizeof(short));
GetFontName(gFormat.font, name);
AddResource(font, 'PFNT', 128, name);
} else {
OSType type;
GetResInfo((Handle) defaultfont, &res, &type, name);
GetFNum(name, &gFormat.font);
if (gFormat.font)
gFormat.size = **defaultfont;
else {
gFormat.font = GetAppFont();
gFormat.size = GetDefFontSize();
}
}
if (!(prefs = (PerlPrefs **) Get1Resource('PPRF', 128))) {
PtrToHand((Ptr) &gPerlPrefs, (Handle *)&prefs, sizeof(PerlPrefs));
AddResource((Handle) prefs, 'PPRF', 128, "\p");
} else
gPerlPrefs = **prefs;
UseResFile(oldResFile);
}
pascal void OpenPreferences()
{
FSSpec prefPath;
CInfoPBRec info;
FCBPBRec fcb;
Str63 name;
gPrefsFile = 0;
GetFNum("\pMonaco", &gFormat.font);
gFormat.size = gFormat.font ? 9 : GetDefFontSize();
gFormat.font = gFormat.font ? gFormat.font : GetAppFont();
fcb.ioNamePtr = &name;
fcb.ioRefNum = CurResFile();
fcb.ioFCBIndx = 0;
PBGetFCBInfoSync(&fcb);
gAppVol = fcb.ioFCBVRefNum;
gAppDir = fcb.ioFCBParID;
prefPath.vRefNum = gAppVol;
prefPath.parID = gAppDir;
PLstrcpy(prefPath.name, "\pMacPerl Preferences");
if (FSpCatInfo(&prefPath, &info))
if (FindFolder(
kOnSystemDisk,
kPreferencesFolderType,
true,
&prefPath.vRefNum,
&prefPath.parID)
)
return;
if (FSpCatInfo(&prefPath, &info)) {
if (HCreate(prefPath.vRefNum, prefPath.parID, prefPath.name, 'McPL', 'pref'))
return;
HCreateResFile(prefPath.vRefNum, prefPath.parID, prefPath.name);
}
OpenPreferenceFile(&prefPath);
}
static short PrefSubDialog = 1;
static short PathCount;
static ListHandle PathList;
pascal void DrawPrefIcon(DialogPtr dlg, short item)
{
short kind;
Handle h;
Rect r;
Str31 title;
FontInfo info;
GetDItem(dlg, item, &kind, &h, &r);
#ifndef RUNTIME
PlotIconID(&r, atNone, (item == PrefSubDialog) ? ttSelected : ttNone, PrefDialog+item);
#else
PlotResICN_(PrefDialog+item, &r, (item == PrefSubDialog) ? iconHilited : iconPlain);
#endif
GetIndString(title, PrefDialog, item);
TextFont(1);
TextSize(9);
GetFontInfo(&info);
MoveTo(r.left - (StringWidth(title) - 32 >> 1), r.bottom+2+info.ascent);
DrawString(title);
if (item == PrefSubDialog) {
r.top = r.bottom + 2;
r.bottom = r.top + info.ascent+info.descent+info.leading+2;
r.left = r.left - (StringWidth(title) - 32 >> 1) - 1;
r.right = r.left + StringWidth(title) + 2;
InvertRect(&r);
}
TextFont(0);
TextSize(12);
}
pascal void DrawPathList(DialogPtr dlg, short item)
{
#pragma unused(item)
Rect r;
TextFont(0);
TextSize(12);
LUpdate(dlg->visRgn, PathList);
r = (*PathList)->rView;
InsetRect(&r, -1, -1);
FrameRect(&r);
}
pascal Boolean PrefLibFilter(DialogPtr dlg, EventRecord * ev, short * item)
{
Point cell;
short kind;
short len;
int length;
Handle h;
Rect r;
WindowPtr win;
char msg[50];
char contents[256];
SetPort(dlg);
switch (ev->what) {
case keyDown:
switch (ev->message & charCodeMask) {
case '\n':
case 3:
*item = pd_Done;
return true;
case 8:
*item = pld_Remove;
return true;
default:
break;
}
case mouseDown:
switch (FindWindow(ev->where, &win)) {
case inDrag:
if (win != dlg)
return false;
r = qd.screenBits.bounds;
InsetRect(&r, 10, 10);
DragWindow(win, ev->where, &r);
ev->what = nullEvent;
return false;
case inSysWindow:
SystemClick(ev, win);
ev->what = nullEvent;
return false;
case inContent:
break;
default:
return false;
}
TextFont(0);
TextSize(12);
cell = ev->where;
GlobalToLocal(&cell);
GetDItem(dlg, pld_List, &kind, &h, &r);
if (PtInRect(cell, &r)) {
if (LClick(cell, ev->modifiers, PathList))
for (SetPt(&cell, 0, 0); LGetSelect(true, &cell, PathList); ++cell.v) {
len = 256;
LGetCell(contents, &len, cell, PathList);
contents[len] = 0;
length = 256;
getindstring(msg, PrefDialog, pd_ChangePath);
if (!choose(AF_FILE, 0, msg, nil, CHOOSE_DEFAULT|CHOOSE_DIR, contents, &length))
LSetCell((Ptr) contents, length, cell, PathList);
}
ev->what = nullEvent;
}
break;
case activateEvt:
LActivate(ev->modifiers & activeFlag, PathList);
break;
case updateEvt:
if ((WindowPtr) ev->message != dlg) {
DoUpdate(DPtrFromWindowPtr((WindowPtr)ev->message));
ev->what = nullEvent;
}
break;
}
return false;
}
static short PrefsLibDialog(DialogPtr prefs, short resFile)
{
short item;
short kind;
short len;
int length;
Boolean done;
Handle h;
Handle paths;
Point cell;
Rect bounds;
Rect dbounds;
char msg[50];
Str255 contents;
UseResFile(gPrefsFile);
paths = Get1Resource('STR#', LibraryPaths);
PathCount = **(short **)paths;
UseResFile(resFile);
#ifndef RUNTIME
h = GetResource('DITL', PrefDialog+PrefSubDialog);
AppendDITL(prefs, h, overlayDITL);
#else
Append_DITL(prefs, PrefDialog+PrefSubDialog);
#endif
GetDItem(prefs, pld_List, &kind, &h, &bounds);
SetDItem(prefs, pld_List, kind, (Handle) DrawPathList, &bounds);
SetPt(&cell, bounds.right - bounds.left, 16);
SetRect(&dbounds, 0, 0, 1, PathCount);
PathList = LNew(&bounds, &dbounds, cell, 0, prefs, false, false, false, true);
UseResFile(gPrefsFile);
SetPt(&cell, 0, 0);
for (; cell.v < PathCount; ++cell.v) {
GetIndString(contents, LibraryPaths, cell.v + 1);
LSetCell((Ptr)contents+1, contents[0], cell, PathList);
}
UseResFile(resFile);
LDoDraw(true, PathList);
ShowWindow(prefs);
for (done = false; !done; ) {
ModalDialog(PrefLibFilter, &item);
switch (item) {
case pd_Done:
case pd_ScriptIcon:
done = true;
break;
case pld_Remove:
SetPt(&cell, 0, 0);
if (LGetSelect(true, &cell, PathList) && Alert(PrefLibDelID, nil) == 1)
do {
LDelRow(1, cell.v, PathList);
--PathCount;
} while (LGetSelect(true, &cell, PathList));
break;
case pld_Add:
length = 256;
getindstring(msg, PrefDialog, pd_AddPath);
if (!choose(AF_FILE, 0, msg, nil, CHOOSE_DIR, contents, &length)) {
SetPt(&cell, 0, PathCount);
LAddRow(1, PathCount++, PathList);
LSetCell(contents, length, cell, PathList);
}
break;
}
}
PtrToXHand(&PathCount, paths, sizeof(short));
SetPt(&cell, 0, 0);
for (; cell.v < PathCount; ++cell.v) {
len = 255;
LGetCell((Ptr) contents+1, &len, cell, PathList);
contents[0] = len;
PtrAndHand(contents, paths, len+1);
}
ChangedResource((Handle) paths);
WriteResource((Handle) paths);
LDispose(PathList);
#ifndef RUNTIME
ShortenDITL(prefs, CountDITL(prefs) - pd_Outline);
#else
Shorten_DITL(prefs, Count_DITL(prefs) - pd_Outline);
#endif
return item;
}
pascal Boolean PrefScriptFilter(DialogPtr dlg, EventRecord * ev, short * item)
{
WindowPtr win;
Rect r;
SetPort(dlg);
switch (ev->what) {
case keyDown:
switch (ev->message & charCodeMask) {
case '\n':
case 3:
*item = pd_Done;
return true;
default:
break;
}
case mouseDown:
switch (FindWindow(ev->where, &win)) {
case inDrag:
if (win != dlg)
return false;
r = qd.screenBits.bounds;
InsetRect(&r, 10, 10);
DragWindow(win, ev->where, &r);
ev->what = nullEvent;
return false;
case inSysWindow:
SystemClick(ev, win);
ev->what = nullEvent;
return false;
default:
return false;
}
case updateEvt:
if ((WindowPtr) ev->message != dlg) {
DoUpdate(DPtrFromWindowPtr((WindowPtr)ev->message));
ev->what = nullEvent;
}
break;
}
return false;
}
static short PrefsScriptDialog(DialogPtr prefs, short resFile)
{
short item;
short kind;
Boolean done;
Handle h;
Handle pref;
Rect bounds;
#ifndef RUNTIME
h = GetResource('DITL', PrefDialog+PrefSubDialog);
AppendDITL(prefs, h, overlayDITL);
#else
Append_DITL(prefs, PrefDialog+PrefSubDialog);
#endif
GetDItem(prefs, psd_Edit, &kind, &h, &bounds);
SetControlValue((ControlHandle) h, !gPerlPrefs.runFinderOpens);
GetDItem(prefs, psd_Run, &kind, &h, &bounds);
SetControlValue((ControlHandle) h, gPerlPrefs.runFinderOpens);
GetDItem(prefs, psd_Check, &kind, &h, &bounds);
SetControlValue((ControlHandle) h, gPerlPrefs.checkType);
for (done = false; !done; ) {
ModalDialog(PrefScriptFilter, &item);
switch (item) {
case pd_Done:
case pd_LibIcon:
done = true;
break;
case psd_Edit:
case psd_Run:
gPerlPrefs.runFinderOpens = item == psd_Run;
GetDItem(prefs, psd_Edit, &kind, &h, &bounds);
SetControlValue((ControlHandle) h, !gPerlPrefs.runFinderOpens);
GetDItem(prefs, psd_Run, &kind, &h, &bounds);
SetControlValue((ControlHandle) h, gPerlPrefs.runFinderOpens);
break;
case psd_Check:
gPerlPrefs.checkType = !gPerlPrefs.checkType;
GetDItem(prefs, psd_Check, &kind, &h, &bounds);
SetControlValue((ControlHandle) h, gPerlPrefs.checkType);
break;
}
}
UseResFile(gPrefsFile);
if (pref = Get1Resource('PPRF', 128)) {
PtrToXHand((Ptr) &gPerlPrefs, pref, sizeof(PerlPrefs));
ChangedResource((Handle) pref);
WriteResource((Handle) pref);
}
UseResFile(resFile);
#ifndef RUNTIME
ShortenDITL(prefs, CountDITL(prefs) - pd_Outline);
#else
Shorten_DITL(prefs, Count_DITL(prefs) - pd_Outline);
#endif
return item;
}
pascal void DoPrefDialog()
{
short resFile;
short kind;
Handle h;
DialogPtr prefs;
Rect bounds;
resFile = CurResFile();
prefs = GetNewDialog(PrefDialog, nil, (WindowPtr) -1);
GetDItem(prefs, pd_LibIcon, &kind, &h, &bounds);
SetDItem(prefs, pd_LibIcon, kind, (Handle) DrawPrefIcon, &bounds);
GetDItem(prefs, pd_ScriptIcon, &kind, &h, &bounds);
SetDItem(prefs, pd_ScriptIcon, kind, (Handle) DrawPrefIcon, &bounds);
GetDItem(prefs, pd_Boundary, &kind, &h, &bounds);
SetDItem(prefs, pd_Boundary, kind, (Handle) Separator, &bounds);
AdornDefaultButton(prefs, pd_Outline);
ShowWindow(prefs);
PrefSubDialog = pd_LibIcon;
PrefSubDialog = PrefsLibDialog(prefs, resFile);
while (PrefSubDialog != pd_Done) {
SetPort(prefs);
InvalRect(&prefs->portRect);
EraseRect(&prefs->portRect);
switch (PrefSubDialog) {
case pd_LibIcon:
PrefSubDialog = PrefsLibDialog(prefs, resFile);
break;
case pd_ScriptIcon:
PrefSubDialog = PrefsScriptDialog(prefs, resFile);
break;
}
}
UpdateResFile(gPrefsFile);
DisposeDialog(prefs);
}
static ListHandle FontList;
static ListHandle SizeList;
pascal void DrawFontList(DialogPtr dlg, short item)
{
#pragma unused(item)
Rect r;
TextFont(0);
TextSize(12);
LUpdate(dlg->visRgn, FontList);
r = (*FontList)->rView;
InsetRect(&r, -1, -1);
FrameRect(&r);
}
pascal void DrawSizeList(DialogPtr dlg, short item)
{
#pragma unused(item)
Rect r;
TextFont(0);
TextSize(12);
LUpdate(dlg->visRgn, SizeList);
r = (*SizeList)->rView;
InsetRect(&r, -1, -1);
FrameRect(&r);
}
static short SizeChoice[] =
{
9,
10,
12,
14,
18,
24
};
const short SizeChoiceCount = 6;
pascal Boolean FormatFilter(DialogPtr dlg, EventRecord * ev, short * item)
{
WindowPtr win;
Rect r;
SetPort(dlg);
switch (ev->what) {
case keyDown:
switch (ev->message & charCodeMask) {
case '\n':
case 3:
*item = fd_OK;
return true;
case '.':
if (!(ev->modifiers & cmdKey))
break;
case 27:
*item = fd_Cancel;
return true;
default:
break;
}
case mouseDown:
switch (FindWindow(ev->where, &win)) {
case inDrag:
if (win != dlg)
return false;
r = qd.screenBits.bounds;
InsetRect(&r, 10, 10);
DragWindow(win, ev->where, &r);
ev->what = nullEvent;
break;
case inSysWindow:
SystemClick(ev, win);
ev->what = nullEvent;
break;
}
return false;
case activateEvt:
LActivate(ev->modifiers & activeFlag, FontList);
LActivate(ev->modifiers & activeFlag, SizeList);
break;
case updateEvt:
if ((WindowPtr) ev->message != dlg) {
DoUpdate(DPtrFromWindowPtr((WindowPtr)ev->message));
ev->what = nullEvent;
}
break;
}
return false;
}
pascal Boolean DoFormatDialog(DocFormat * form, Boolean * defaultFormat)
{
short item;
short kind;
short digit;
Boolean done;
Handle h;
DialogPtr format;
Point cell;
Rect bounds;
Rect dbounds;
Str255 contents;
MenuHandle fonts;
format = GetNewDialog(FormatDialog, nil, (WindowPtr) -1);
GetDItem(format, fd_Separator, &kind, &h, &bounds);
SetDItem(format, fd_Separator, kind, (Handle) Separator, &bounds);
GetDItem(format, fd_FontList, &kind, &h, &bounds);
SetDItem(format, fd_FontList, kind, (Handle) DrawFontList, &bounds);
fonts = NewMenu(FormatDialog, "\pFonts");
AppendResMenu(fonts, 'FONT');
bounds.right -= 16;
SetPt(&cell, bounds.right - bounds.left, 16);
SetRect(&dbounds, 0, 0, 1, CountMItems(fonts));
FontList = LNew(&bounds, &dbounds, cell, 0, format, false, false, false, true);
SetPt(&cell, 0, 0);
for (; cell.v < CountMItems(fonts); ++cell.v) {
GetItem(fonts, cell.v+1, contents);
LSetCell((Ptr)contents+1, contents[0], cell, FontList);
GetFNum(contents, &kind);
LSetSelect(form->font == kind, cell, FontList);
}
GetDItem(format, fd_SizeList, &kind, &h, &bounds);
SetDItem(format, fd_SizeList, kind, (Handle) DrawSizeList, &bounds);
bounds.right -= 16;
SetPt(&cell, bounds.right - bounds.left, 16);
SetRect(&dbounds, 0, 0, 1, SizeChoiceCount);
SizeList = LNew(&bounds, &dbounds, cell, 0, format, false, false, false, true);
SetPt(&cell, 0, 0);
for (; cell.v < SizeChoiceCount; ++cell.v) {
sprintf((char *) contents, "%d", SizeChoice[cell.v]);
LSetCell((Ptr)contents, strlen((Ptr) contents), cell, SizeList);
LSetSelect(form->size == SizeChoice[cell.v], cell, SizeList);
}
AdornDefaultButton(format, fd_Outline);
LDoDraw(true, FontList);
LDoDraw(true, SizeList);
sprintf((char *) contents+1, "%d", form->size);
contents[0] = strlen((Ptr) contents+1);
SetText(format, fd_SizeEdit, contents);
SelIText(format, fd_SizeEdit, 0, 32767);
if (*defaultFormat) {
GetDItem(format, fd_MakeDefault, &kind, &h, &bounds);
SetControlValue((ControlHandle) h, 1);
HiliteControl((ControlHandle) h, 254);
}
ShowWindow(format);
for (done = false; !done; ) {
ModalDialog(FormatFilter, &item);
switch (item) {
case fd_OK:
RetrieveText(format, fd_SizeEdit, contents);
if (contents[0]) {
for (digit = 0, kind = 0; digit++ < contents[0]; )
if (isdigit(contents[digit]))
kind = kind * 10 + contents[digit] - '0';
else {
kind = 0;
break;
}
if (kind) {
form->size = kind;
SetPt(&cell, 0, 0);
LGetSelect(true, &cell, FontList);
GetItem(fonts, cell.v+1, contents);
GetFNum(contents, &kind);
form->font = kind;
done = true;
break;
}
}
SelIText(format, fd_SizeEdit, 0, 32767);
SysBeep(0);
item = 0;
break;
case fd_Cancel:
done = true;
*defaultFormat = false;
break;
case fd_FontList:
GetMouse(&cell);
LClick(cell, 0, FontList);
break;
case fd_SizeList:
GetMouse(&cell);
LClick(cell, 0, SizeList);
SetPt(&cell, 0, 0);
if (LGetSelect(true, &cell, SizeList)) {
sprintf((char *) contents+1, "%d", SizeChoice[cell.v]);
contents[0] = strlen((Ptr) contents+1);
SetText(format, fd_SizeEdit, contents);
SelIText(format, fd_SizeEdit, 0, 32767);
}
break;
case fd_MakeDefault:
GetDItem(format, fd_MakeDefault, &kind, &h, &bounds);
SetControlValue((ControlHandle) h, *defaultFormat = !*defaultFormat);
break;
}
}
LDispose(FontList);
LDispose(SizeList);
DisposeDialog(format);
DisposeMenu(fonts);
return (item == fd_OK);
}